package com.atguigu.srb.common.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

/**
 * MD5加密工具类
 * 提供字符串的MD5加密功能
 */
public final class MD5 {

    // 防止实例化
    private MD5() {
    }

    // 十六进制字符数组
    private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 对输入字符串进行MD5加密
     *
     * @param str 待加密的字符串
     * @return 加密后的32位十六进制字符串
     * @throws RuntimeException 当系统不支持MD5算法时抛出
     */
    public static String encrypt(String str) {
        // 处理空值
        if (str == null) {
            return null;
        }

        try {
            // 获取MD5消息摘要实例
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 计算哈希值
            byte[] hashBytes = md.digest(str.getBytes());

            // 转换为十六进制字符串
            return bytesToHex(hashBytes);

        } catch (NoSuchAlgorithmException e) {
            // 这种情况理论上不会发生，因为MD5是标准算法
            throw new RuntimeException("系统不支持MD5算法", e);
        }
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        Objects.requireNonNull(bytes);

        char[] resultChars = new char[bytes.length * 2];
        int index = 0;

        for (byte b : bytes) {
            // 高4位转换为十六进制
            resultChars[index++] = HEX_CHARS[(b >>> 4) & 0xF];
            // 低4位转换为十六进制
            resultChars[index++] = HEX_CHARS[b & 0xF];
        }

        return new String(resultChars);
    }
}